from typing import List

from business_processes.opening_account_validation.domain.entity.document import (
    AccountDocument,
)
from business_processes.opening_account_validation.domain.entity.package import (
    AccountPackage,
)
from business_processes.opening_account_validation.domain.entity.page import (
    AccountDocumentPage,
)

from core.domain.enums import PackageStatus

from core.domain.core_domain_value_objects.document_cutter import (
    DocumentCutter,
)
from core.domain.core_domain_value_objects.pages_classifier import (
    PagesClassifier,
)
from core.domain.core_domain_value_objects.pages_entities_extractor import (
    PageEntitiesExtractor,
)


class OpeningAccountCheckService:

    document_cutter = DocumentCutter()
    pages_classifier = PagesClassifier()
    pages_entities_extractor = PageEntitiesExtractor()

    def check_all_document_pages_classes_are_the_same(self, classes: List) -> bool:
        return classes.count(classes[0]) == len(classes)

    def run_business_process(self, package: AccountPackage):
        documents_info = package.documents
        documents = {}

        for document_class, document in documents_info:
            pages_paths = self.document_cutter.cut_document_to_pages(
                document_path=document
            )
            pages = [
                AccountDocumentPage(page_file_path=page_file_path)
                for page_file_path in pages_paths
            ]
            documents[document_class] = AccountDocument(
                expected_class=document_class, pages=pages
            )

            page_classes = [self.pages_classifier.classify_page(page=page, expected_class=document_class) for page in pages]
            document_class_valid = self.check_all_document_pages_classes_are_the_same(classes=page_classes)

            if not document_class_valid:
                package.assign_status(status=PackageStatus.invalid)
                return package

            document.assign_document_class(doc_class=page_classes[0])

            for page in pages:
                page.add_page_text(text=self.pages_entities_extractor.extract_page_entities(page=page))

            document.update_document_pages(pages=pages)

        package_status_integrity = package.validate_package_integrity()
        if package_status_integrity == PackageStatus.invalid:
            package.assign_status(status=package_status_integrity)

            return package

        package_status_processing = package.run_business_logic()
        package.assign_status(status=package_status_processing)

        return package
